package com.jinzheng.qhnetty.util.testjinzhengclient;
import com.jinzheng.qhnetty.util.HexUtils;
import com.jinzheng.qhnetty.util.testjinzhengclient.CheckClientInitializer1;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @CLassName NettyServer
 **/
public class NettyServer {

    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //创建服务端的启动对象 配置参数
            ServerBootstrap bootstrap = new ServerBootstrap();
            //使用链式编程进行设置
            /**
             * 1.设置两个线程组
             * 2.使用 NioSocketChannel 作为服务器的通道实现
             * 3.设置线程队列得到的连接数
             * 4.设置保持活动连接状态
             * 5.给我们的 WorkerGroup 的 EventLoop 对应的管道设置处理器
             */
            bootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,128)
                    .childOption(ChannelOption.SO_KEEPALIVE,true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        //给 PipLine 设置处理器
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addLast(new CheckClientInitializer1());
                        }
                    });
            System.out.println("Server is Ready");
            //绑定一个端口并且同步 生成了一个 ChannelFuture 对象 启动服务
            ChannelFuture cf = bootstrap.bind(7788).sync();
            //对关闭通道进行侦听
            cf.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    static class NettyServerHandler extends ChannelInboundHandlerAdapter {
        /**
         * 读取数据
         * @param ctx 上下文对象 含有 管道 pipLine 通道 Channel 地址
         * @param message 客户端发送的数据
         */
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
//            System.out.println("Server Read Thread :" + Thread.currentThread().getName());
//            System.out.println("Server ctx=" + ctx);
        //将message转成一个ByteBuf
//            ByteBuf buf = (ByteBuf) message;
//            System.out.println("Client Send Message is:" + buf.toString(CharsetUtil.UTF_8));
        System.out.println("Client Ip Address is:" + ctx.channel().remoteAddress());
            sendMsg(ctx);
        }

        /**
         * 读取数据完毕
         * @param ctx
         * @throws Exception
         */
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        }

        public void sendMsg(ChannelHandlerContext ctx){
            String GPS_TXT = "232302FE4C45575445423134374D4E3130323935320100B7160712130929010203010000000022000000000000020F000000000201010328FFFFFFFF280096FFFF050006AFA5C901EA2C4E060101000201010001010102010101070000000000000000000801010000000000010001010CE409010100013C0A00540300000000001A0000000000000100010001000100000000FFFF02000001002FEA0A7F1E6465706F7433323936302E666C79626565732E636F6D2E636E3A36363538010000001F00010000000000000000000000FB";
            //将数据写入到缓冲区并刷新
            System.out.println("发送数据:" + ctx.channel().remoteAddress());
            byte[] data = HexUtils.fromHexString(GPS_TXT);
            byte[] newData = new byte[data.length - 3];
            System.arraycopy(data, 2, newData, 0, newData.length);
            System.arraycopy("L0000000000000001".getBytes(), 0, newData, 2, 17);
            {
                SimpleDateFormat sp = new SimpleDateFormat("yyMMddHHmmss");
                long ymdhms = Long.parseLong(sp.format(new Date(System.currentTimeMillis())));
                int idx = 22;
                newData[idx++] = (byte) (ymdhms / 10000000000L);//年
                newData[idx++] = (byte) (ymdhms / 100000000L % 100);//月
                newData[idx++] = (byte) (ymdhms / 1000000L % 100);//日
                newData[idx++] = (byte) (ymdhms / 10000L % 100);//时
                newData[idx++] = (byte) (ymdhms / 100L % 100);//分
                newData[idx++] = (byte) (ymdhms % 100);//秒
            }
            byte[] escapeData = escape(newData);
            ctx.writeAndFlush(escapeData);
        }

        public byte[] escape(byte[] origin) {
            byte[] escapes = new byte[origin.length + 3];
            int idx = 0;
            escapes[idx++] = 0x23;
            escapes[idx++] = 0x23;
            byte checkCode = 0x00;
            for (byte ele : origin) {
                checkCode ^= ele;
                escapes[idx++] = ele;
            }
            escapes[idx++] = checkCode;
    //        log.info("发送数据：" + HexUtils.toHexString(escapes));
            return escapes;
        }

        /**
         * 处理异常 一般为关闭通道
         * @param ctx
         * @param cause
         * @throws Exception
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
        }
    }


}
